﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Web;
using System.Runtime.Remoting.Messaging;

namespace Api.Common
{
    #region 日志類型枚舉
    /// <summary>
    /// 日志類型枚舉
    /// </summary>
    public enum LogType : byte
    {
        /// <summary>
        /// 普通信息
        /// </summary>
        Info,

        /// <summary>
        /// 錯誤信息
        /// </summary>
        Error,

        /// <summary>
        /// 电邮时的发送信息
        /// </summary>
        EmailInfo,

        /// <summary>
        /// 电邮发送时的错误信息
        /// </summary>
        EmailError,

        /// <summary>
        /// 取消订单时的信息
        /// </summary>
        CancelOrderInfo,

        /// <summary>
        /// 取消订单时的错误信息
        /// </summary>
        CancelOrderError,

        /// <summary>
        /// 文件保存时的错误信息
        /// </summary>
        MakeThumbnailError,

        /// <summary>
        /// 文件保存时的错误信息
        /// </summary>
        FileSaveError,

        /// <summary>
        /// 文件删除时的错误信息
        /// </summary>
        FileDeleteError,

        /// <summary>
        /// 文件删除出错时的文件记录
        /// </summary>
        FileDeleteErrorRecord,

        /// <summary>
        /// able.web中路由信息记录
        /// </summary>
        UrlRoutingInfo,

        /// <summary>
        /// 付款日志
        /// </summary>
        Payment,

        /// <summary>
        /// PayPal付款数据日志
        /// </summary>
        PayPalPaymentData,

        /// <summary>
        /// 支付定付款数据日志
        /// </summary>
        AlipayPaymentData,

        /// <summary>
        /// 微信支付付款数据日志
        /// </summary>
        WeChatPayPaymentData,
        /// <summary>
        /// 删除数据库Info
        /// </summary>
        CleanupInfo,
        /// <summary>
        /// 删除数据库Error
        /// </summary>
        CleanupError,
        SignalrInfo,
        SignalrError,
        Request,
        /// <summary>
        /// 取消订单时添加推送通知
        /// </summary>
        CancleOrderPush,
    }
    #endregion

    #region 日志助手類
    /// <summary>
    /// 日志助手類
    /// </summary>
    public class LogHelper
    {
        #region 當前助手類對象
        /// <summary>
        /// 當前助手類對象
        /// </summary>
        public static LogHelper CurrHelper
        {
            get
            {
                LogHelper bll = CallContext.GetData(typeof(LogHelper).Name) as LogHelper;
                if (bll != null)
                {
                    return bll;
                }
                else
                {
                    bll = new LogHelper();
                    CallContext.SetData(typeof(LogHelper).Name, bll);
                    return bll;
                }
            }
        }
        #endregion

        #region public Method
        public static void WriteRequestLog(string content)
        {
            CurrHelper.WriteLog(LogType.Request, content);
        }
        public static void WriteInfoLog(string content)
        {
            CurrHelper.WriteLog(LogType.Info, content);
        }
        public static void WriteShortInfoLog(string content)
        {
            CurrHelper.WriteCreateNewLog(LogType.Info, content);
        }
        public static void WriteErrorLog(string content)
        {
            CurrHelper.WriteLog(LogType.Error, content);
        }

        public static void WriteSignalrInfoLog(string content)
        {
            CurrHelper.WriteLog(LogType.SignalrInfo, content);
        }

        public static void WriteSignalrErrorLog(string content)
        {
            CurrHelper.WriteLog(LogType.SignalrError, content);
        }

        /// <summary>
        /// 寫入发送邮件成功的日志（哪些时成功发送的邮件）
        /// </summary>
        /// <param name="content">日志內容</param>
        public static void WriteEmailInfoLog(string content)
        {
            CurrHelper.WriteLog(LogType.EmailInfo, content);
        }

        /// <summary>
        /// 寫入发送邮件过程中出现的任何错误
        /// </summary>
        /// <param name="content">日志內容</param>
        public static void WriteEmailErrorLog(string content)
        {
            CurrHelper.WriteLog(LogType.EmailError, content);
        }

        /// <summary>
        /// 写入付款日志
        /// </summary>
        /// <param name="orderNoInfo">订单编号信息 订单编号-网站Id</param>
        /// <param name="content">日志内容</param>
        public static void WritePaymentLog(string orderNoInfo, string content)
        {
            CurrHelper.WriteLog(LogType.Payment, orderNoInfo + "," + content);
        }

        /// <summary>
        /// 写入PayPal付款数据日志
        /// </summary>
        /// <param name="orderNoInfo">订单编号信息 订单编号-网站Id</param>
        /// <param name="content">日志内容</param>
        public static void WritePayPalPaymentDataLog(string orderNoInfo, string content)
        {
            CurrHelper.WriteLog(LogType.PayPalPaymentData, orderNoInfo + "," + content);
        }

        /// <summary>
        /// 写入支付宝付款数据日志
        /// </summary>
        /// <param name="orderNoInfo">订单编号信息 订单编号-网站Id</param>
        /// <param name="content">日志内容</param>
        public static void WriteAlipayPaymentDataLog(string orderNoInfo, string content)
        {
            CurrHelper.WriteLog(LogType.AlipayPaymentData, orderNoInfo + " " + content);
        }

        /// <summary>
        /// 写入微信支付付款数据日志
        /// </summary>
        /// <param name="orderNoInfo">订单编号信息 订单编号-网站Id</param>
        /// <param name="content">日志内容</param>
        public static void WriteWeChatPayPaymentDataLog(string orderNoInfo, string content)
        {
            CurrHelper.WriteLog(LogType.WeChatPayPaymentData, orderNoInfo + "," + content);
        }

        /// <summary>
        /// 寫入取消订单的日志（哪些时成功发送的邮件）
        /// </summary>
        /// <param name="content">日志內容</param>
        public static void WriteCancelOrderInfoLog(string content)
        {
            CurrHelper.WriteLog(LogType.CancelOrderInfo, content);
        }

        /// <summary>
        /// 寫入取消订单过程中出现的任何错误
        /// </summary>
        /// <param name="content">日志內容</param>
        public static void WriteCancelOrderErrorLog(string content)
        {
            CurrHelper.WriteLog(LogType.CancelOrderError, content);
        }
        /// <summary>
        /// 写入添加订单提醒过程中出现的错误
        /// </summary>
        /// <param name="content"></param>
        public static void WriteAddCancleOrderPushInfoLog(string content)
        {
            CurrHelper.WriteLog(LogType.CancleOrderPush, content);
        }

        /// <summary>
        /// 写入添加订单提醒过程中出现的错误
        /// </summary>
        /// <param name="content"></param>
        public static void WriteAddCancleOrderPushErrorLog(string content)
        {
            CurrHelper.WriteLog(LogType.CancleOrderPush, content);
        }

        /// <summary>
        /// 寫入生成缩略图出现的任何错误
        /// </summary>
        /// <param name="content">日志內容</param>
        public static void WriteMakeThumbnailErrorLog(string content)
        {
            CurrHelper.WriteLog(LogType.MakeThumbnailError, content);
        }

        /// <summary>
        /// 寫入保存文件出现的任何错误
        /// </summary>
        /// <param name="content">日志內容</param>
        public static void WriteFileSaveErrorLog(string content)
        {
            CurrHelper.WriteLog(LogType.FileSaveError, content);
        }

        /// <summary>
        /// 寫入删除文件出现的任何错误
        /// </summary>
        /// <param name="content">日志內容</param>
        public static void WriteFileDeleteErrorLog(string content)
        {
            CurrHelper.WriteLog(LogType.FileDeleteError, content);
        }

        /// <summary>
        /// 寫入删除文件出现错时的文件记录
        /// </summary>
        /// <param name="content">日志內容</param>
        public static void WriteFileDeleteErrorRecordLog(string content)
        {
            CurrHelper.WriteLog(LogType.FileDeleteErrorRecord, content);
        }

        public static void WriteUrlRoutingInfoLog(string content)
        {
            CurrHelper.WriteLog(LogType.UrlRoutingInfo, content);
        }

        public static void WriteCleanDataError(string content)
        {
            CurrHelper.WriteLog(LogType.CleanupError, content);
        }

        #endregion

        /// <summary>
        /// 寫入日志
        /// </summary>
        /// <param name="logType">日志類型</param>
        /// <param name="content">日志內容</param>
        public void WriteLog(LogType logType, string content)
        {
            string newLine = System.Environment.NewLine;
            var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            var index = baseDirectory.IndexOf("bin", StringComparison.OrdinalIgnoreCase);
            if (index > 0)
            {
                baseDirectory = baseDirectory.Remove(index);
            }

            string path = baseDirectory + @"log\" + logType + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + " - " + logType.ToString() + ".txt";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
            }
            try
            {
                //采用追加模式来写日志
                using (var fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Write))
                {
                    StreamWriter writer = new StreamWriter(fs, Encoding.UTF8);
                    var str = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + newLine + content + newLine + newLine;
                    writer.WriteLine(str);
                    writer.Flush();
                }
            }
            catch (Exception)
            {

            }
        }

        /// <summary>
        /// 始終都是創建新的文件
        /// </summary>
        /// <param name="content"></param>
        public void WriteCreateNewLog(LogType logType, string content)
        {
            string newLine = System.Environment.NewLine;
            var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            var index = baseDirectory.IndexOf("bin", StringComparison.OrdinalIgnoreCase);
            if (index > 0)
            {
                baseDirectory = baseDirectory.Remove(index);
            }

            string path = baseDirectory + @"log\" + logType + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + " - " + logType.ToString() + ".txt";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
            }
            try
            {
                using (var fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    StreamWriter writer = new StreamWriter(fs, Encoding.UTF8);
                    var str = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + newLine + content + newLine + newLine;
                    writer.WriteLine(str);
                    writer.Flush();
                }
            }
            catch (Exception)
            {

            }
        }

        public static void WriteExceptionLog(System.Exception ex)
        {
            var newLine = Environment.NewLine;
            var sbContent = new StringBuilder();
            sbContent.AppendLine("//**********************************************************************************************************************");
            sbContent.AppendLine("异常时间：(" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ")");
            sbContent.AppendLine("出错页面：(" + HttpContext.Current.Request.Url.ToString() + ")");
            if (HttpContext.Current.Request.UrlReferrer != null)
            {
                sbContent.AppendLine("来源页面：(" + HttpContext.Current.Request.UrlReferrer.ToString() + ")");
            }

            sbContent.AppendLine("访问IP：(" + HttpContext.Current.Request.UserHostAddress + ")");
            sbContent.AppendLine("异常信息：(" + ex.Message + ")");
            sbContent.AppendLine("异常方法：(" + ex.TargetSite + ")");
            sbContent.AppendLine("异常来源：(" + ex.Source + ")");
            sbContent.AppendLine("异常处理：" + newLine + ex.StackTrace);
            sbContent.AppendLine("异常实例：" + newLine + ex.InnerException);
            sbContent.AppendLine("//**********************************************************************************************************************");
            LogHelper.WriteErrorLog(sbContent.ToString()); //寫入日志
        }
    }
    #endregion
}
